package render;

import math.Vecmath;

public class ColorMap
{
    
    protected int numPixelsX;
    public int getNumPixelsX() { return this.numPixelsX; }
    
    protected int numPixelsY;
    public int getNumPixelsY() { return this.numPixelsY; }
    
    protected double[][][] pixels;
    
    public ColorMap(
            int pixelsWide, 
            int pixelsTall)
    {
        this.numPixelsX = pixelsWide;
        this.numPixelsY = pixelsTall;
        
        this.pixels = new double[this.numPixelsY][this.numPixelsX][3];
    }
    
    public void addColor(int indexX, int indexY, double[] color)
    {
        Vecmath.translate(this.pixels[indexY][indexX], color);
    }
    
    public double[] getColor(int indexX, int indexY)
    {
        return this.pixels[indexY][indexX];
    }
    
    public void limitComponentsOfScanline(int indexY)
    {
        for (int indexX = 0; indexX < this.numPixelsX; indexX++)
        {
            Vecmath.limitComponents(this.pixels[indexY][indexX], 0.0, 1.0);
        }
    }
    
    public void clearData()
    {
        for (int indexY = 0; indexY < this.numPixelsY; indexY++)
        {
            for (int indexX = 0; indexX < this.numPixelsX; indexX++)
            {
                for (int indexVec = 0; indexVec < 3; indexVec++)
                {
                    this.pixels[indexY][indexX][indexVec] = 0.0;
                }
            }
        }
    }
    
    public void blendDataBilinear(int step)
    {
        for (int indexY = 0; indexY < this.numPixelsY; indexY++)
        {
            for (int indexX = 0; indexX < this.numPixelsX; indexX++)
            {
                this.blendBilinear(indexX, indexY, step);
            }
        }
    }
    
    private void blendBilinear(int indexX, int indexY, int step)
    {
        int numAdded = 0;
        double[] accumColor = new double[3];
        if (indexX >= step)
        {
            Vecmath.translate(accumColor, this.getColor(indexX - step, indexY));
            numAdded++;
        }
        else
        {
            Vecmath.translate(accumColor, this.getColor(indexX, indexY));
            numAdded++;
        }
        if (indexX < (this.numPixelsX - step))
        {
            Vecmath.translate(accumColor, this.getColor(indexX + step, indexY));
            numAdded++;
        }
        else
        {
            Vecmath.translate(accumColor, this.getColor(indexX, indexY));
            numAdded++;
        }
        if (indexY >= step)
        {
            Vecmath.translate(accumColor, this.getColor(indexX, indexY - step));
            numAdded++;
        }
        else
        {
            Vecmath.translate(accumColor, this.getColor(indexX, indexY));
            numAdded++;
        }
        if (indexY < (this.numPixelsY - step))
        {
            Vecmath.translate(accumColor, this.getColor(indexX, indexY + step));
            numAdded++;
        }
        else
        {
            Vecmath.translate(accumColor, this.getColor(indexX, indexY));
            numAdded++;
        }
        Vecmath.scale(accumColor, 1.0 / numAdded);
        this.pixels[indexY][indexX] = accumColor;
    }
    
}
